深入理解Webpack Loader:处理模块的工具
Howard 9/14/2023 Webpack
在前一篇文章中,我们已经讨论了 Webpack 的生命周期和如何编写自定义的 Plugin。这次,让我们来深入了解 Webpack 的另一个核心部分 - Loader。
# Webpack 的生命周期和 Loader 的作用
Webpack 的生命周期可以分为三个阶段:准备阶段、编译阶段和产出阶段。Loader 主要发挥作用的阶段是编译阶段。默认情况下,Webpack 只能打包 CommonJS 规范的 JavaScript 文件,因此需要 Loader 来处理不同类型的文件,并将它们转换为可以理解的模块。
# Webpack 的执行上下文
在自定义 loader 的时候,Webpack 仅仅会把正则匹配的文件的源码当作参数传入,其他有用的信息需要通过执行上下文this
去获取。
Webpack 提供loader-utils
工具去方便开发者去开发 loader,推荐使用v1 版本 (opens new window),最常用的就是loaderUtils.getOptions(this)
去获取 loader 的传入参数
除了使用 loader-utils 之外,默认this
也有很多实用的方法供开发者使用。
this.query
,也是获取传入参数,如果有配置 options 的话就获取该对象,没有获取去?
开头的字符串,当然官方推荐使用 loader-utils 去获取参数this.callback
,用于返回结果的函数,用于同步或者异步返回结果。
this.callback(
err: Error | null,
content: string | Buffer,
sourceMap?: SourceMap,
meta?: any
);
this.async
,异步返回函数。
const loaderUtils = require('loader-utils');
module.exports = function(source) {
const callback = this.async();
setTimeout(() => {
callback(null, '12345');
}, 200)
}
this.emitFile
,文件写入,url-loader
就通过这个函数去实现文件写入
const loaderUtils = require('loader-utils');
module.exports = function(content) {
const url = loaderUtils.interpolateName(this, "[name].[ext]", {
content,
});
this.emitFile(url, content);
this.callback(null, content);
}
更多的API (opens new window)可以参考
# Loader 开发环境
Webpack 提供了[loader-runnder](https://github.com/webpack/loader-runner)
的开发工具,让开发者可以脱离 webpack 的环境去开发 loader。
// my-loader.js
module.exports = function(source) {
const json = JSON.stringify(source)
.replace('howard', 'Howard');
return `export default ${json}`;
}
然后在根目录创建一个 run.js 文件
// run-loader.js
const { runLoaders } = require('loader-runner');
const fs = require('fs');
const path = require('path');
runLoaders({
resource: path.join(__dirname, './me.txt'),
loaders: [
{
loader: path.join(__dirname, './src/my-loader.js'),
}
],
context: {},
readResource: fs.readFile.bind(fs)
}, (err, result) => {
err ? console.log(err) : console.log(result);
});
# 常用的 Loader
Loader 名字 | 官网地址 | 作用 |
---|---|---|
babel-loader | https://github.com/babel/babel-loader | 前端现代神器,必备,万能的 js 转换器,React,Vue,Typescript 常用。 |
style-loader | https://github.com/webpack-contrib/style-loader | 一个用于在浏览器中加载样式文件的 webpack 加载器。 |
css-loader | https://github.com/webpack-contrib/css-loader | 用于处理 webpack 中的 CSS 文件,将其转换为可被浏览器理解的模块。 |
postcss-loader | https://github.com/webpack-contrib/postcss-loader | 一个用于在 webpack 构建过程中自动处理 CSS 的加载器,可用于执行各种 CSS 处理和优化任务。 |
sass-loader | https://github.com/webpack-contrib/sass-loader | 用于在 webpack 构建过程中处理 Sass 文件,将其转换为普通的 CSS 样式。 |
url-loader | https://github.com/webpack-contrib/url-loader | 用于处理文件资源,特别是图像和字体文件,它可以将小文件转换为 base64 数据 URL,以减少 HTTP 请求并提高性能。但目前在 Webpack5 中,更推荐使用 type: asset 去处理文件 |
vue-loader | https://github.com/vuejs/vue-loader | 一个用于处理 Vue.js 单文件组件的 webpack 加载器,它将.vue 文件中的模板、样式和脚本部分提取出来并进行编译,以便在浏览器中正确渲染 Vue 组件。 |